package com.adt.studioms.web.controller.user;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.lang.math.NumberUtils;
import org.springframework.validation.BindException;
import org.springframework.validation.Errors;
import org.springframework.validation.Validator;
import org.springframework.web.servlet.ModelAndView;

import com.adt.studioms.StudiomsApplication;
import com.adt.studioms.api.PhotoSizeAPI;
import com.adt.studioms.api.ServiceAPI;
import com.adt.studioms.api.TaskAPI;
import com.adt.studioms.om.PhotoSize;
import com.adt.studioms.om.Service;
import com.adt.studioms.om.Task;
import com.asao.baseware.core.security.ITrustedPassport;
import com.asao.baseware.core.web.controller.EntityCommand;
import com.asao.baseware.core.web.controller.EntityFormController;

public class ServiceController extends EntityFormController<ServiceCommand> {
    ServiceAPI serviceAPI;
    TaskAPI taskAPI;
    PhotoSizeAPI psAPI;

    class ServiceValidator implements Validator {

        public boolean supports(Class clazz) {
            return clazz.equals(ServiceCommand.class);
        }

        public void validate(Object target, Errors errors) {
            ServiceCommand cmd = (ServiceCommand) target;
            
            if (cmd.getTaskId()==0) {
                errors.rejectValue("taskId", "service.taskIsRequired", "Task is required");
            }
            
            if (cmd.getAction()==EntityCommand.CREATE || cmd.getAction()==EntityCommand.UPDATE) {
                Service s = serviceAPI.get(cmd.getTaskId(), cmd.getPhotoSizeId());
                if (s!=null && s.getId()!=cmd.getId()) {
                    errors.rejectValue("taskId", "service.taskAndPhotoSizeIsExisted", "Service with current task and photo size is existed");
                    errors.rejectValue("photoSizeId", "service.taskAndPhotoSizeIsExisted", "Service with current task and photo size is existed");
                }
            }
            
            if (!NumberUtils.isNumber(cmd.getPrice())) {
                errors.rejectValue("price", "service.priceIsNotValid", "Price is not valid. It must be a number");
            }
        }
    }
    
    public ServiceController() {
        super();
        serviceAPI = StudiomsApplication.instance.getApiRegistry().lookupAPI(ITrustedPassport.instance, ServiceAPI.class);
        taskAPI = StudiomsApplication.instance.getApiRegistry().lookupAPI(ITrustedPassport.instance, TaskAPI.class);
        psAPI = StudiomsApplication.instance.getApiRegistry().lookupAPI(ITrustedPassport.instance, PhotoSizeAPI.class);

        setCommandClass(ServiceCommand.class);
        setValidator(new ServiceValidator());
    }

    protected void publishEntity(long id, ServiceCommand command) {
        Service service = serviceAPI.get(id);
        if (service!=null) {
            command.setId(service.getId());
            Task task = service.getTask();
            command.setTaskId(task!=null ? task.getId() : 0);
            PhotoSize photoSize = service.getPhotoSize();
            command.setPhotoSizeId(photoSize!=null ? photoSize.getId() : 0);
            command.setPrice(service.getPrice()+"");
        }
    }

    protected void createEntity(ServiceCommand command, BindException errors) {
        Service s = serviceAPI.createService(command.getTaskId(), command.getPhotoSizeId(), command.price());
        command.setId(s.getId());
    }

    protected void updateEntity(ServiceCommand command, BindException errors) {
        serviceAPI.updateService(command.getId(), command.getTaskId(), command.getPhotoSizeId(), command.price());
    }

    protected void deleteEntity(ServiceCommand command, BindException errors) {
        serviceAPI.delete(command.getId());
    }

    protected ModelAndView handleRequestInternal(HttpServletRequest request, HttpServletResponse response) throws Exception {
        ModelAndView mv = super.handleRequestInternal(request, response);
        
        mv.addObject("tasks", taskAPI.list());
        mv.addObject("photoSizes", psAPI.list());
        
        return mv;
    }
}

class ServiceCommand extends EntityCommand {
    long taskId;
    long photoSizeId;
    String price;

    public long getTaskId() {
        return taskId;
    }

    public void setTaskId(long taskId) {
        this.taskId = taskId;
    }

    public long getPhotoSizeId() {
        return photoSizeId;
    }

    public void setPhotoSizeId(long photoSizeId) {
        this.photoSizeId = photoSizeId;
    }

    public String getPrice() {
        return price;
    }

    public void setPrice(String price) {
        this.price = price;
    }
    
    long price() {
        return NumberUtils.toLong(price);
    }
}